package alex.game.playerIO
{
	import alex.game.updatable.map.MapFactory;
	import alex.game.util.GameUtil;
	import alex.game.util.Player;
	
	import com.framework.GG;
	import com.framework.util.Log;
	
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	
	import playerio.Client;
	import playerio.Connection;
	import playerio.Message;
	import playerio.PlayerIO;
	import playerio.PlayerIOError;

	public class PlayerIOManager extends EventDispatcher
	{
		private static var instance:PlayerIOManager;
		
		public static var PLAYERIO_EVENT_CONNECTED:String = "playerIO_connected";
		public static var PLAYERIO_EVENT_ERROR:String = "playerIO_error";
		public static var PLAYERIO_EVENT_ROOM_JOINED:String = "playerIO_roomJoined";
		public static var PLAYERIO_EVENT_SERVICE_ROOM_JOINED:String = "playerIO_serviceRoomJoined";
		public static var PLAYERIO_EVENT_JOINING_GAME_ROOM:String = "playerIO_joiningGameRoom";
		
		
		private var client:Client;
		
		private var currentConnection:Connection;
		private var lastConnection:Connection;
		private var waitingMatchConnection:Connection;
		
		

		public static function getInstance():PlayerIOManager
		{
			if(instance == null)
				instance = new PlayerIOManager();
			
			return instance;
		}
		
		public function getCurrentClient():Client
		{
			return this.client;
		}
		public function getCurrentConnection():Connection
		{
			return this.currentConnection;
		}
		
		public function connectToPlayerIO(username:String):void
		{
			PlayerIO.connect(GG.stage,"unchartedskies-realtime-y97gfjgb90wtuxjbmqe6xa","public",username,"","",connectedHandler);
		}
		public function createJoinRoom(id:String,type:String, roomData:Array=null,joinData:Array=null):void
		{
			client.multiplayer.createJoinRoom(
				id,								//Set a random ID
				type,							//Type of room
				true,
				roomData,						//Room data
				joinData,						//join data
				roomJoined,
				function(e:PlayerIOError):void{ 
					Log.debug(this,e.message) 
					dispatchEvent(new Event(PLAYERIO_EVENT_ERROR));
				}
			);
		}
		private function roomJoined(connection:Connection):void
		{
			Log.debug(this,"Room Joined");
			if(this.currentConnection != null)
				this.lastConnection = currentConnection;
			
			this.currentConnection = connection;
			dispatchEvent(new Event(PLAYERIO_EVENT_ROOM_JOINED));
		}
		private function connectedHandler(client:Client):void
		{
			this.client = client;
			client.multiplayer.developmentServer = "127.0.0.1:8184";
			dispatchEvent(new Event(PLAYERIO_EVENT_CONNECTED));
		}
		public function connectToMatchMaking(service_game_mode:String):void
		{
			
			//Rejoins la liste d'attente
			this.client.multiplayer.createJoinRoom(
				service_game_mode,               //Room id. If set to null a random roomid is used
				"MatchMaking",                        //The game type started on the server
				false,                          //Should the room be hidden from the lobby?
				{},                             //Room data. This data is returned to lobby list. Variabels can be modifed on the server
				{username:GameUtil.player.username}, 		//User join data
				handleServiceWaitingMatchRoomJoined,                //Function executed on successful joining of the room
				function(e:PlayerIOError):void{ 
					Log.debug(this,e.message) 
					dispatchEvent(new Event(PLAYERIO_EVENT_ERROR));
				}
			);
			
		}
		private function handleServiceWaitingMatchRoomJoined(connection:Connection):void
		{
			this.waitingMatchConnection = connection;
			dispatchEvent(new Event(PLAYERIO_EVENT_SERVICE_ROOM_JOINED));
			this.waitingMatchConnection.addMessageHandler(GameUtil.PROTOCOLE_STARTING_GAME,startingGameHandler);
		}
		/**
		 * Récupère :
		 * 0 : L'id de la room à rejoindre
		 * 1 : Le type de game (ffa-ctf etc...)
		 * 2 : Le nombre de joueurs
		 * 
		 * 
		 * */
		private function startingGameHandler(msg:Message):void
		{
			this.waitingMatchConnection.removeMessageHandler(GameUtil.PROTOCOLE_STARTING_GAME,startingGameHandler);
			
			dispatchEvent(new Event(PLAYERIO_EVENT_JOINING_GAME_ROOM));
			
			var roomID:String = msg.getString(0);
			var gameType:String = msg.getString(1);
			var map:String = msg.getString(2);
			var nbrPlayers:int = msg.getInt(3);
			
			Log.debug(this,"Nombre de joueurs : "+nbrPlayers);
			
			var playerI:int = 0;
			var player:Player = new Player();
			var players:Array = new Array();
			for(var i:int = 4; i <(4+(nbrPlayers*2));i++)
			{
				if(playerI < 3){
					playerI++;
				}else{
					playerI = 0;
				}
					
				if(i%2 == 0){
					
					player.username = msg.getString(i);
					Log.debug(this, "username : "+msg.getString(i));
					
				}else{
					player.connectedUserId = msg.getString(i);
					players.push(player);
					player = new Player();
					Log.debug(this, "connectedUserId : "+msg.getString(i));
					
				}
				
			}
			
			//Set les players de la game
			GameUtil.players = players;
			
			//Set la map de la game
			GameUtil.map = map;
			
			//Set le mode de la game
			GameUtil.gameType = gameType;
			
			Log.debug(this,"Starting game, roomID : "+roomID);
			
			//Indique le type de room lors de sa création
			var roomData:Array = new Array();
			roomData.push(gameType);
			roomData.push(map);
			
			createJoinRoom(roomID,"GameRoom",roomData);
		}
		
		
		
		public function clean():void
		{
			try{
				this.currentConnection.disconnect();
				this.currentConnection = null;
			}catch(e:Error){}
			try{
				this.lastConnection.disconnect();
				this.lastConnection = null;
			}catch(e:Error){}
			
			this.client = null;
		}
	}
}